/**
 * Copyright 2009-2010 - YangJiandong(chunquedong)
 * 
 * This file is part of ChunMap project
 * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE(Version >=3)
 * 你可以自由复制、传播本项目的下载包文件，但必须保持其完整性。
 * 我们不用对使用中的风险及由此造成的损失承担任何责任。
 * 详细情况请见《ChunMap许可协议》。

 * 想了解更多有关ChunMap的信息，请访问http://code.google.com/p/chunmap/
 */
package chunmap.view.render;

import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.geom.Area;

import chunmap.model.coord.Position;
import chunmap.model.geom.GeoPoint;
import chunmap.model.geom.Geometry;
import chunmap.model.geom.LineString;
import chunmap.model.geom.Ring;
import chunmap.model.geom.Polygon;
import chunmap.view.View;

/**
 * @author chunquedong
 * 
 */
public class DrawHelper {
	
	private Style2D style;
	
	public void drawImage(Graphics2D g,Image image,int x,int y,int w,int h){
		g.drawImage(image, x, y, w, h, null);
	}

	public void drawPoint(Graphics2D g, Geometry geo,View view) {

		int pointSize = style.getPointSize();
		double half = pointSize / 2d;

		GeoPoint p = (GeoPoint) geo;
		double x = view.x2Screen(p.getX()) - half;
		double y = view.y2Screen(p.getY()) - half;

		g.setPaint(style.getPointColor());
		g.setStroke(style.getStroke());

		g.fillOval((int) x, (int) y, pointSize, pointSize);
	}

	public void drawLineString(Graphics2D g, Geometry geo,View view) {
		g.setPaint(style.getLineColor());
		g.setStroke(style.getStroke());

		LineString ls = (LineString) geo;

		int[] xa=getXa(ls,view);
		int[] ya=getYa(ls,view);
		
		g.drawPolyline(xa, ya, ls.size());

		if (style.isNeedPoint()) {
			drawPoints4Line(g, ls, style,view);
		}
	}
	
	private int[] getXa(LineString ls,View view){
		int n=ls.size();
		int[] xa=new int[n];
		double[] a=ls.getPoints().getXa();
		for(int i=0;i<n;i++){
			int x=(int)view.x2Screen(a[i]);
			xa[i]=x;
		}
		return xa;
	}
	
	private int[] getYa(LineString ls,View view){
		int n=ls.size();
		int[] ya=new int[n];
		double[] a=ls.getPoints().getYa();
		for(int i=0;i<n;i++){
			int y=(int)view.y2Screen(a[i]);
			ya[i]=y;
		}
		return ya;
	}

	public void drawPolygon(Graphics2D g, Geometry geo,View view) {
		Polygon pg = (Polygon) geo;
		Ring shell = pg.getShell();
		java.awt.Polygon shellPaht = createPolygon(shell,view);
		//shellPaht.closePath();
		Area area = new Area(shellPaht);
		for (Ring r : pg.getHoles()) {
			java.awt.Polygon holePath = createPolygon(r,view);
			//holePath.closePath();
			Area holeArea = new Area(holePath);
			area.subtract(holeArea);
		}

		g.setStroke(style.getStroke());
		if (style.isNeedArea()) {
			g.setPaint(style.getAreaColor());
			g.fill(area);
		}
		if (style.isNeedLine()) {
			g.setPaint(style.getLineColor());
			g.draw(area);
		}
		if (style.isNeedPoint()) {
			drawPoints4Line(g, shell, style,view);
			for (Ring r : pg.getHoles()) {
				drawPoints4Line(g, r, style,view);
			}
		}
	}

//	private GeneralPath toGeneralPath(LineString ls) {
//		GeneralPath path = new GeneralPath();
//		path.moveTo(ls.firstPoint().getX(), ls.firstPoint().getY());
//		for (int i = 1, n = ls.size(); i < n; i++) {
//			path.lineTo(ls.getPoint(i).getX(), ls.getPoint(i).getY());
//		}
//		return path;
//	}
	
	private java.awt.Polygon createPolygon(Ring ls,View view){
		return new java.awt.Polygon(getXa(ls,view), getYa(ls,view), ls.size());
	}

	private void drawPoints4Line(Graphics2D g, LineString ls, Style2D style,View view) {
		for (int i = 1, n = ls.size(); i < n; i++) {
			Position p = ls.getPoint(i);

			int pointSize = style.getPointSize();
			double half = pointSize / 2d;

			double x = view.x2Screen(p.getX()) - half;
			double y = view.y2Screen(p.getY()) - half;

			g.setPaint(style.getPointColor());
			g.setStroke(style.getStroke());

			g.drawRect((int) x, (int) y, pointSize, pointSize);
		}
	}

	public void setStyle(Style2D style) {
		this.style = style;
	}

}
